from openpyxl import Workbook
from openpyxl.styles import Alignment, Font, PatternFill, Border, Side
from openpyxl.utils import get_column_letter
from typing import List, Dict, Optional


class BatteryCycleDataWriter:
    """
    电池循环数据表格生成器类
    """
    
    def __init__(self, data_config: List[Dict]):
        """
        初始化电池循环数据表格生成器
        
        Args:
            data_config: 数据配置字典列表
        """
        self.data_config = data_config
        self.wb = Workbook()
        self.ws = self.wb.active
        self.ws.title = "循环过程数据"
        
        # 定义样式
        self.header_fill = PatternFill(start_color="92D050", end_color="92D050", fill_type="solid")
        self.header_font = Font(bold=True, color="000000")
        self.center_alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)
        
        # 定义边框样式
        self.thin_border = Border(
            left=Side(style='thin'),
            right=Side(style='thin'),
            top=Side(style='thin'),
            bottom=Side(style='thin')
        )
        
        # 分离列配置
        self.base_columns = ["循环次数"]
        self.charge_columns = []
        self.discharge_columns = []
        
        self._process_data_config()
        
    def _process_data_config(self):
        """处理数据配置，分离充电和放电列"""
        for item in self.data_config:
            column_name = item["column"]
            status = item["status"]
            method = item["method"]
            small_cycle = item["small_cycle"]
            # 构建完整的列名
            if column_name in ["SOC", "最大温度", "最小温度", "最大电压", "最小电压"]:
                full_name = f"{column_name}_{method}"
            elif column_name in ["最大电压节数", "最小电压节数"]:
                full_name = f"{column_name}_{method}"
            else:
                full_name = column_name
            if method in ['最大值', "最小值", "起始值", "截止值"]:
                if not full_name.endswith(method):
                    full_name = full_name + "_" + method

            if small_cycle:
                full_name += f"_小循环{small_cycle}"
            if status == "充电":
                self.charge_columns.append(full_name)
            elif status == "放电":
                self.discharge_columns.append(full_name)
            else:
                self.base_columns.append(full_name)
        # 排序
        self.charge_columns = sorted(self.charge_columns)
        self.discharge_columns = sorted(self.discharge_columns)
    
    def _merge_cells(self):
        """合并单元格"""
        total_columns = len(self.base_columns) + len(self.charge_columns) + len(self.discharge_columns)
        
        # 第一行：主标题合并
        self.ws.merge_cells(f'A1:{get_column_letter(total_columns)}1')
        
        # 基础列的合并
        for i in range(len(self.base_columns)):
            col_letter = get_column_letter(i + 1)
            self.ws.merge_cells(f'{col_letter}2:{col_letter}3')
        
        # 充电区域的合并
        if self.charge_columns:
            charge_start_col = len(self.base_columns) + 1
            charge_end_col = charge_start_col + len(self.charge_columns) - 1
            self.ws.merge_cells(f'{get_column_letter(charge_start_col)}2:{get_column_letter(charge_end_col)}2')
        
        # 放电区域的合并
        if self.discharge_columns:
            discharge_start_col = charge_end_col + 1 if self.charge_columns else len(self.base_columns) + 1
            discharge_end_col = discharge_start_col + len(self.discharge_columns) - 1
            self.ws.merge_cells(f'{get_column_letter(discharge_start_col)}2:{get_column_letter(discharge_end_col)}2')
    
    def _set_header_content(self):
        """设置表头内容"""
        
        # 第一行：主标题
        self.ws['A1'] = "循环过程数据"
        self.ws['A1'].fill = self.header_fill
        self.ws['A1'].font = self.header_font
        self.ws['A1'].alignment = self.center_alignment
        
        # 基础列
        for i, col_name in enumerate(self.base_columns):
            col_letter = get_column_letter(i + 1)
            cell = self.ws[f'{col_letter}2']
            cell.value = col_name
            cell.fill = self.header_fill
            cell.font = self.header_font
            cell.alignment = self.center_alignment
        
        # 充电区域标题
        if self.charge_columns:
            charge_start_col = len(self.base_columns) + 1
            charge_cell = self.ws.cell(row=2, column=charge_start_col, value="充电")
            charge_cell.fill = self.header_fill
            charge_cell.font = self.header_font
            charge_cell.alignment = self.center_alignment
        
        # 放电区域标题
        if self.discharge_columns:
            discharge_start_col = len(self.base_columns) + len(self.charge_columns) + 1
            discharge_cell = self.ws.cell(row=2, column=discharge_start_col, value="放电")
            discharge_cell.fill = self.header_fill
            discharge_cell.font = self.header_font
            discharge_cell.alignment = self.center_alignment
        
        # 第三行：具体的列名称
        # 充电列
        for i, col_name in enumerate(self.charge_columns):
            col_num = len(self.base_columns) + i + 1
            cell = self.ws.cell(row=3, column=col_num, value=col_name)
            cell.fill = self.header_fill
            cell.font = self.header_font
            cell.alignment = self.center_alignment
        
        # 放电列
        for i, col_name in enumerate(self.discharge_columns):
            col_num = len(self.base_columns) + len(self.charge_columns) + i + 1
            cell = self.ws.cell(row=3, column=col_num, value=col_name)
            cell.fill = self.header_fill
            cell.font = self.header_font
            cell.alignment = self.center_alignment
    
    def _apply_borders(self):
        """应用边框样式"""
        total_columns = len(self.base_columns) + len(self.charge_columns) + len(self.discharge_columns)
        
        # 为表头区域（1-3行）的所有单元格添加边框
        for row in range(1, 4):
            for col in range(1, total_columns + 1):
                cell = self.ws.cell(row=row, column=col)
                cell.border = self.thin_border
    
    def create_header(self):
        """创建表格表头"""
        self._merge_cells()
        self._set_header_content()
        self._apply_borders()
    
    def add_data_row(self, row_data: List, row_num: int):
        """
        添加数据行
        
        Args:
            row_data: 行数据列表
            row_num: 行号
        """
        for col_num, value in enumerate(row_data, 1):
            cell = self.ws.cell(row=row_num, column=col_num, value=value)
            cell.border = self.thin_border
            cell.alignment = Alignment(horizontal="center", vertical="center")
    
    def set_column_widths(self, widths: Optional[Dict] = None):
        """
        设置列宽
        
        Args:
            widths: 列宽字典，格式为 {列字母: 宽度值}
        """
        if widths is None:
            # 默认列宽
            for col in range(1, len(self.base_columns) + len(self.charge_columns) + len(self.discharge_columns) + 1):
                self.ws.column_dimensions[get_column_letter(col)].width = 15
        else:
            for col_letter, width in widths.items():
                self.ws.column_dimensions[col_letter].width = width
    
    def save(self, filename: str):
        """
        保存工作簿
        
        Args:
            filename: 文件名
        """
        self.wb.save(filename)
        print(f"表格已保存为 '{filename}'")


# 使用示例
if __name__ == "__main__":
    # 这是你提供的字典列表
    data_config = [
        {"column": "SOC", "status": "放电", "method": "截止值"},
        {"column": "最大温度", "status": "放电", "method": "起始值"},
        {"column": "最小温度", "status": "放电", "method": "起始值"},
        {"column": "最大温度", "status": "放电", "method": "截止值"},
        {"column": "最大电压", "status": "放电", "method": "截止值"},
        {"column": "最小电压", "status": "放电", "method": "截止值"},
        {"column": "最大电压节数", "status": "放电", "method": "截止值"},
        {"column": "最小电压节数", "status": "放电", "method": "截止值"},
        {"column": "充电容量", "status": "充电", "method": "截止值"},
        {"column": "充电能量", "status": "充电", "method": "截止值"},
        {"column": "SOC", "status": "充电", "method": "起始值"},
        {"column": "SOC", "status": "充电", "method": "截止值"},
        {"column": "最大温度", "status": "充电", "method": "起始值"},
        {"column": "最小温度", "status": "充电", "method": "起始值"},
        {"column": "最大电压", "status": "充电", "method": "截止值"},
        {"column": "最大电压节数", "status": "充电", "method": "截止值"},
        {"column": "最小电压", "status": "充电", "method": "截止值"},
        {"column": "最小电压节数", "status": "充电", "method": "截止值"},
        {"column": "放电容量", "status": "放电", "method": "截止值"},
        {"column": "放电能量", "status": "放电", "method": "截止值"},
        {"column": "SOC", "status": "放电", "method": "起始值"}
    ]
    
    # 创建电池循环数据写入器实例
    battery_writer = BatteryCycleDataWriter(data_config)
    
    # 创建表头
    battery_writer.create_header()
    
    # 设置列宽
    battery_writer.set_column_widths()
    
    # 添加示例数据行
    sample_data = [1, 100.0, 98.5] + [None] * (len(data_config) - 3)  # 填充示例数据
    battery_writer.add_data_row(sample_data, 4)
    
    # 保存文件
    battery_writer.save("电池循环数据表头_正确边框.xlsx")